/**
 * Framework Remendux - http://code.google.com/p/remendux/
 * @description Desenvolvimento de um Framework Ajax para auxiliar em cursos e tutoriais 
 * de javascript avançado. 
 * Auxílio na prova de conceito nos diversos módulos e contextos que necessita um 
 * framework ajax. Nome cedido gentilmente por Rafael Ponte www.rponte.com.br 
 * Nome inspirado nas famosas gambiarras que são necessárias para o desenvolvimento
 *  Cross Browser. 
 *  
 * @namespace RX
 * @author Christiano Milfont
 * @version 0.0.1
 * @since 0.0.1
 */
var RX = {
	/**
	 * Version of Framework
	 * @memberOf RX
	 * @public
	 */
	version:'0.0.1',
	/**
	 * Name of Framework
	 * @memberOf RX
	 * @public
	 */
	name:'REMENDUX'
};

(function() {


  /**
   * Objeto privado que modela os metodos de captura da chamada $
   * @constructor
   * @param {Object} arguments Objetos ou Strings que representam o identificador dos objetos
   * @return {this}
   */
  function _$(els) {
    this.elements = [];
    for (var i=0; i<els.length; i++) {
      var element = els[i];
      if (typeof element == 'string') {
        element = document.getElementById(element);
      };
      this.elements.push(element);
    };
    return this;
  };

  _$.prototype = {
  	/**
  	 * Percorre a lista de elementos aplicando uma function a cada um durante a iteração
  	 * @member RX
  	 * @param {Object} fn Function que será aplicada a todos os elementos
  	 * @returns {this}
  	 */
    each: function(fn) {
      for ( var i = 0, len = this.elements.length; i<len; ++i ) {
        fn.call(this, this.elements[i]);
      };
      return this;
    },
	/**
	 * Aplica um estilo aos elementos capturados
	 * @member RX
	 * @param {Object} prop Propriedade css
	 * @param {Object} val Valor da propriedade
	 * @returns {this}
	 */
    setStyle: function(prop, val) {
      this.each(function(el) {
        el.style[prop] = val;
      });
      return this;
    },
	/**
	 * Adiciona um seletor css aos elementos capturados
	 * @member RX
	 * @param {Object} className nome do seletor
	 * @returns {this}
	 */
    addClass: function(className) {
      this.each(function(el) {
        el.className += ' '+className;
      });
      return this;
    },
	/**
	 * Metodo que adiciona um evento aos elementos capturados
	 * @member RX
	 * @deprecated
	 * @param {Object} type
	 * @param {Object} fn
	 * @returns {this}
	 */
    on: function(type, fn) {
      var listen = function(el) {
        if (window.addEventListener) {
          el.addEventListener(type, fn, false);
        } else if (window.attachEvent) {
          el.attachEvent('on'+type, function() {
            fn.call(el, window.event);
          });
        };
      };
      this.each(function(el) {
        listen(el);
      });
      return this;
    },
	/**
	 * Adiciona estilos a partir de um array
	 * @member RX
	 * @param {Object} o
	 * @returns {this}
	 */
    css: function(o) {
      var that = this;
      this.each(function(el) {
        for (var prop in o) {
          that.setStyle(prop, o[prop]);
        };
      });
      return this;
    }
  };
  
  /**
   * Captura um Element para encapsular métodos amigaveis de tratamento DOM e BOM
   * @param {object[]} arguments Objetos ou Strings que representam o identificador dos objetos
   * @return RX._$
   * @member RX
   */
  RX.$ = function() {
    return new _$(arguments);
  };

	/**
	 * @private
	 */
	var isIE = false;
	/**
	 * Function Crossbrowser que insere um listener responsável de tratar eventos 
	 * @function
	 * @param {Object} el Objeto que será alvo de um evento
	 * @param {Object} type Tipo de evento
	 * @param {Object} fn Function que servirá como Listener ao evento
	 */
	RX.addEvent = function(el, type, fn) {
		el['on'+type] = fn;
	};

	if(document.addEventListener) {
		RX.addEvent = function(el, type, fn) {
			el.addEventListener(type, fn, false);
		};
	} else if(document.attachEvent) {
		isIE = true;
		RX.addEvent = function(el, type, fn) {
			el.attachEvent('on'+type, fn);
		};
	};
	/**
	 * Function que instancia um XHR Crossbrowser
	 * @function
	 * @returns {XMLHttpRequest}
	 */
	RX.getXHR = function() {
		this.http = new XMLHttpRequest;
		return this.http;
	};
	if(isIE) {
		/**
		 * @private
		 */
		var msxml = ['MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
		for (var i=0, len = msxml.length; i < len; ++i) {
			try {
				http = new ActiveXObject(msxml[i]);
				RX.getXHR = function() {
					return new ActiveXObject(msxml[i]);
				};
				break;
			} catch(e) {};
		};
	};
	/**
	 * Function que copia propriedades de um objeto para outro
	 * @function
	 * @param {Object} el Objeto que rereberá a cópia das propriedades
	 * @param {Object} cp Objeto que fornecerá a cópia de propriedades
	 */
	RX.merge = function(el, cp) {
		for(i in cp) {
			if( typeof cp[i] == 'object') {
				if(el[i] == undefined) {
					el[i] = cp[i]
				}
				RX.merge(el[i], cp[i]);
			} else {
				el[i] = cp[i];
			}
		}
	};


})();